package net.wofly.sale.order.service;

import com.alipay.api.AlipayApiException;
import net.wofly.common.persistence.PageWrapper;
import net.wofly.framework.util.ReturnBean;
import net.wofly.sale.commodity.domain.CommodityTerminal;
import net.wofly.sale.order.domain.Order;
import net.wofly.sale.order.domain.OrderStatusDto;
import net.wofly.sale.order.domain.OrderType;
import net.wofly.sale.order.dto.req.BanquetOrderReq;
import net.wofly.sale.order.dto.req.NoMoneyOrderReq;
import net.wofly.sale.order.dto.req.ReturnGoodsOrderReq;
import net.wofly.sale.order.dto.resp.ReturnGoodsDtoResp;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

public interface ISaleOrderService {
    
    /**
     * 增加或修改
     *
     * @param entity
     * @return
     */
    public Order save(Order entity);
    
    /**
     * 删除
     *
     * @param entity
     * @return
     */
    public void delete(Order entity);
    
    /**
     * 根据主键ID删除
     *
     * @param key
     * @return
     */
    public void delete(String key);
    
    /**
     * 根据主键查询
     *
     * @param key
     * @return
     */
    public Order findOne(String key);
    
    public Object findMaxOrderNoByDate(String dateStr);
    
    public List<Order> save(List<Order> entityList);
    
    public Page<Order> findAll(Specification specification, Pageable pageable);
    
    /**
     * @param order
     */
    public ReturnBean<Order> createOrder(Order order) throws CloneNotSupportedException;
    
    public CommodityTerminal getCommodityTerminal(String orderType, String commodityChannelID);
    
    public ReturnBean<Order> handleOrder(Order order) throws CloneNotSupportedException;
    
    /**
     * 获取客户订单，包括客户自己下单及销售代为下单的所有订单
     * <ul>
     * <li> </li>
     * </ul>
     *
     * @param customerID
     */
    public ReturnBean<PageWrapper<Order>> getCustomerOrder(String customerID, Integer pageNum, Integer pageSize);
    
    /**
     * @param orderID
     */
    public ReturnBean<Order> getOrder(String orderID);
    
    /**
     * 获取销售订单
     * <ul>
     * <li>是指定销售所管理的所有客户订单。</li>
     * <li>需要先获取所有其管理的客户列表，然后取得所有订单</li>
     * <li>placeOrderType 不传时，为所有订单</li>
     * <li>customer 不传时为所有客户</li>
     * <li></li>
     * </ul>
     *
     * @param salerID
     * @param orderNo
     * @param orderType
     * @param customerName
     * @param status
     */
    public ReturnBean<PageWrapper<Order>> getSalerOrder(
            String salerID, String orderNo, Integer orderType, String customerName, Integer status, Integer pageNum,
            Integer pageSize);
    
    
    /**
     * 根据条件获取订单
     * <ol>
     * <li></li>
     * </ol>
     *
     * @param orderNo
     * @param orderType
     * @param customerName
     * @param status
     * @param pageNum
     * @param pageSize
     */
    public ReturnBean<PageWrapper<Order>> getOrderByCnd(
            String orderNo, Integer orderType, String customerName, Integer status, Long startTime, Long endTime,  Integer pageNum, Integer pageSize);
    
    public ReturnBean<Order> getOrder(String orderID, Integer payType);
    
    public ReturnBean<String> pay(
            String orderID, Integer payType, Integer clientType,
            BigDecimal price) throws IOException, AlipayApiException;
    
    ReturnBean<Order> getVerifyOrder(String userID, String order) throws CloneNotSupportedException;
    
    public void orderTimeoutRefresh();
    
    public ReturnBean<String> cancelOrder(String orderID, Integer orderStatus);
    
    List<Order> findByPayTimeIsNullAndPayDeadlineLessThan(Long payDeadline);
    
    List<Order> findByPlaceOrderTypeAndStatusAndOrderTypeNotAndPayDeadlineLessThan(
            Integer placeOrderType, Integer status, Integer orderType, Long payDeadline);
    
    /**
     * 获取所有订单类型
     *
     * @return
     */
    public ReturnBean<List<OrderType>> getAllOrderTypes();
    
    /**
     * 根据角色获取订单类型
     *
     * @param roleID
     */
    public ReturnBean<List<OrderType>> getOrderTypeByRole(String roleID) throws CloneNotSupportedException;
    
    /**
     * 获取订单状态
     */
    public ReturnBean<List<OrderStatusDto>> getOrderStatus();
    
    /**
     * 通过工作流实例ID列表查找所有ID的订单
     *
     * @param processInsIDs
     * @return
     */
    public List<Order> findByInProcessInsID(List<String> processInsIDs);
    
    /**
     * 通过工作流实例ID查找订单
     *
     * @param processInsID
     * @return
     */
    public Order findByProcessInsID(String processInsID);
    
    /**
     * 更改订单类型
     *
     * @param orderType
     * @param order
     * @return
     */
    public ReturnBean<Order> changeOrderType(Integer orderType, Order order) throws CloneNotSupportedException;
    
    /**
     * 重新写入订单的真正支付信息，向payInfo表插入记录
     *
     * @param orderID
     * @return
     */
    public ReturnBean<String> reWritePayInfo4WorkFlowConfirmReceiveable(String orderID);
    
    
    /**
     * 获取客户的还货商品库存
     *
     * @param customerUserID
     * @return
     */
    public ReturnBean<List<ReturnGoodsDtoResp>> getCustomerReturnGoodsStock(String customerUserID);
    
    /**
     * 创建订单（还货订单专用）
     *
     * @param returnGoodsOrderReq
     * @return
     */
    public ReturnBean<Order> createOrderForReturnGoods(ReturnGoodsOrderReq returnGoodsOrderReq);
    
    /**
     * 创建订单（无款订单专用），只是为了销库存
     * @return
     */
    public ReturnBean<Order> createNoMoneyOrder(NoMoneyOrderReq noMoneyOrderReq);
    
    /**
     * 修改订单（无款订单专用），只是为了销库存
     * @return
     */
    public ReturnBean<Order> updateNoMoneyOrder(Order order);
    
    /**
     * 删除订单（无款订单专用）
     * @return
     */
    public ReturnBean<String> deleteNoMoneyOrder(String orderID);
    
    /**
     * 创建宴会订单（宴会订单专用）
     * @return
     */
    public ReturnBean<Order> createBanquetOrder(BanquetOrderReq banquetOrderReq) throws CloneNotSupportedException;
    
    /**
     * 修改宴会订单（宴会订单专用）
     * @return
     */
    public ReturnBean<Order> updateBanquetOrder(Order order);
    
    /**
     * 删除宴会订单（宴会订单专用）
     * @return
     */
    public ReturnBean<String> deleteBanquetOrder(String orderID);
    
    /**
     * 宴会订单减库存（宴会订单专用）
     * @return
     */
    public ReturnBean<Order> decreaseStockForBanquetOrder(String orderID);
    
    /**
     * 无款订单减库存
     * @param orderID
     * @return
     */
    public ReturnBean<Order> decreaseStockForNoMoneyOrder(String orderID);
    
    /**
     * 获取订单待办
     *
     * @param userID
     * @return
     */
    public List<Order> findToDoList(String userID);
    
    /**
     * 获取工作流中订单详情
     *
     * @param orderID
     * @return
     */
    public ReturnBean<Order> getOrderForFlow(String orderID);
    
    /**
     * 获取我的订单
     *
     * @param userID
     * @param orderNo
     * @param orderType
     * @param customerName
     * @param status
     * @param pageNum
     * @param pageSize
     * @return
     */
    public ReturnBean<PageWrapper<Order>> getMyOrders(
            String userID, String orderNo, Integer orderType, String customerName, Integer status, Integer pageNum,
            Integer pageSize);
    
    List<Order> findByBuyerAndOrderCommitTimeBetween(String userID, Long startTime, Long endTime);
    
    List<Order> findByBuyerAndFinishedTimeBetween(String userID, Long startTime, Long endTime);
    
    List<Order> findByBuyerAndPayTimeBetween(String userID, Long startTime, Long endTime);
    
    /**
     * 检查订单是否有赠品（给工作流用，白条订单发货时，才进行减库存，如果有赠品，则继续调用减库存接口，反之则不调用）
     *
     * @param orderID
     * @return
     */
    public boolean checkOrderHasGift(String orderID);
    
    /**
     * 支付方式为白条订单的减库存（给工作流用）
     *
     * @param orderID
     * @return
     */
    ReturnBean<String> decreaseStockForBaiTiaoOrder(String orderID);
    
    
    public ReturnBean<PageWrapper<Order>> getMyOrdersByStatus(
            String userID, String orderNo, Integer orderType, String customerName, Integer status, Integer pageNum,
            Integer pageSize);
    
}
